package java_thinking.unit_17.clone;

import lombok.Data;

/**
 * @Desc:
 * @author: cww
 * @DateTime: 2019-04-27 14:22
 */
@Data
public class School implements Cloneable{


    private String schoolName;
    private int stuNumbs;
    private Student stu;

    @Override
    protected School clone() throws CloneNotSupportedException {
        return (School)super.clone();
    }

    @Override
    public String toString() {
        return "School{" +
                "schoolName='" + schoolName + '\'' +
                ", stuNumbs=" + stuNumbs +
                ", stu=" + stu +
                '}';
    }

    /**
     * 浅度克隆测试
     * 1.理论上这里s1与s2的hashcode不同(但是打印出来就是一样)，也就是说clone方法并不是把s1的引用赋予s2，而是在堆中重新开辟了一
     *  块空间，将s1复制过去，将新的地址返回给s2
     * 2. 但是s1中stu的hashcode与s2中stu的hashcode相同，也就是这两个指向了同一个对象，修改s2中的stu会造成s1中stu数据的改变。
     *  但是修改s2中的基本数据类型与Stirng类型时，不会造成s1中数据的改变，基本数据类型例如int，在clone的时候会重新开辟一个四个
     *  字节的大小的空间，将其赋值。而String则由于String变量的唯一性，如果在s2中改变了String类型的值，则会生成一个新的String
     *  对象，对之前的没有影响。  这就是浅度克隆
     *
     * @param args
     * @throws CloneNotSupportedException
     */
    public static void main(String[] args) throws CloneNotSupportedException {
        School s1 = new School();
        s1.setSchoolName("实验小学");
        s1.setStuNumbs(100);

        Student stu1 = new Student();
        stu1.setAge(29);
        stu1.setName("ww");
        stu1.setSex(new StringBuffer("男"));

        s1.setStu(stu1);
        System.out.println("s1: "+s1+" s1的hashcode:"+s1.hashCode()+"  s1中stu1的hashcode:"+s1.getStu().hashCode());
        School s2 = s1.clone();
        System.out.println("s2: "+s2+" s2的hashcode:"+s2.hashCode()+"  s2中stu1的hashcode:"+s2.getStu().hashCode());
        s2.setSchoolName("new School");
        s2.getStu().setAge(32);
        System.out.println("s1: "+s1+" s1的hashcode:"+s1.hashCode()+"  s1中stu1的hashcode:"+s1.getStu().hashCode());
        System.out.println("s2: "+s2+" s2的hashcode:"+s2.hashCode()+"  s2中stu1的hashcode:"+s2.getStu().hashCode());



    }


}
